﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.ServiceModel;
using System.ServiceModel.Channels;
using System.Text;
using System.Threading.Tasks;

namespace WJP.DataPortal.WCF
{
    /// <summary>
    /// 
    /// </summary>
    public class Invoker
    {
        private ChannelFactory<IRoutingService> cf;
        private int retries = 0;
        private RoutingFilter filter;
        private MessageBuffer messageBuffer;

        /// <summary>
        /// 
        /// </summary>
        /// <param name="message"></param>
        public Invoker(Message message)
        {
            this.messageBuffer = message.CreateBufferedCopy(int.MaxValue);
            this.filter = RoutingManager.Currrent.GetFilter(message.Headers.To.AbsolutePath);
            this.cf = new ChannelFactory<IRoutingService>(this.filter.Endpoint);
        }

        /// <summary>
        /// 
        /// </summary>
        /// <returns></returns>
        public Message Invoke()
        {
            HostInfo host = RoutingManager.Currrent.GetHost();
            Message result;
            try
            {
                Message message = this.cf.CreateChannel(RoutingManager.Currrent.CreateEndpoint(host, this.filter.Address)).Invoke(this.messageBuffer.CreateMessage());
                HostManager.Default.Success(host);
                if (cf != null)
                    this.cf.Close();
                result = message;
            }
            catch (Exception ex)
            {
                HostManager.Default.Faild(host);
                if(this.retries < RoutingManager.MaxRetries)
                {
                    this.cf.Abort();
                    throw ex;
                }
                retries++;
                result = Invoke();
            }

            return result;
        }
    }
}
